import type { PatchState } from "@rivet/state";
export interface History {
  past: PatchState[];
  present: PatchState | null;
  future: PatchState[];
  index: number;
  _latestUnfiltered: PatchState | null;
}
/* 历史记录管理器
 负责记录历史操作，并提供撤销和重做功能
 */
export class HistoryManager {
  limit: number = -1;
  history: History;
  constructor(limit = Infinity, ignoreInitialState = false) {
    this.limit = limit;
    this.history = this.createHistory();
    if (ignoreInitialState) {
      this.history._latestUnfiltered = null;
    }
  }
  createHistory(
    past: PatchState[] = [],
    present: PatchState | null = null,
    future: PatchState[] = [],
  ): History {
    return {
      past,
      present,
      future,
      index: past.length,
      _latestUnfiltered: present,
    };
  }
  insert(state: PatchState) {
    const { past } = this.history;
    const lengthWithoutFuture = past.length + 1;
    const isHistoryOverflow = this.limit && this.limit <= lengthWithoutFuture;
    const pastSliced = past.slice(isHistoryOverflow ? 1 : 0);
    const newPast = this.history._latestUnfiltered != null
      ? [...pastSliced, this.history._latestUnfiltered]
      : pastSliced;
    this.history = this.createHistory(newPast, state, []);
  }
  //往前跳
  jumpToFuture(index: number) {
    if (index < 0 || index >= this.history.future.length) return;
    const { past, _latestUnfiltered, future } = this.history;
    const newPast = [...past, _latestUnfiltered, ...future.slice(0, index)];
    const newPresent = future[index];
    const newFuture = future.slice(index + 1);
    // @ts-ignore: ignore
    this.history = this.createHistory(newPast, newPresent, newFuture);
  }
  //往后跳
  jumpToPast(index: number) {
    if (index < 0 || index >= this.history.past.length) return;
    const { past, future, _latestUnfiltered } = this.history;
    const newPast = past.slice(0, index);
    const newFuture = [...past.slice(index + 1), _latestUnfiltered, ...future];
    const newPresent = past[index];
    // @ts-ignore: ignore
    this.history = this.createHistory(newPast, newPresent, newFuture);
  }
  // 跳到任意位置 n代表步数 负数代表倒退
  jump(n: number) {
    if (n > 0) this.jumpToFuture(n - 1);
    else if (n < 0) this.jumpToPast(this.history.past.length + n);
  }
  // 清空历史记录
  clearHistory() {
    this.history = this.createHistory([], this.history.present, []);
  }
}
